package com.fit.spring.boot.proxy.interceptor.extension;

import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.Map;

import org.aopalliance.intercept.MethodInterceptor;

import com.fit.spring.boot.proxy.interceptor.utils.ReflectUtil;

/**
 * 拦截器配置接口
 * 根据指定的注解过滤目标方法
 * 
 * @author hcl
 *
 */
public abstract class InterceptorConfigurationAware extends InterceptorConfiguration {

	/**
	 * 设置此注解后,只有当目标类或目标方法上有此注解时才会调用getBeanMethodInterceptorsKeys方法
	 */
	private Class<Annotation>[] targetAnnotations;
	
	{
		targetAnnotations = this.getTargetAnnotations();
	}
	

	/**
	 * 注册拦截器
	 * 
	 * @return
	 */
	public abstract MethodInterceptor registeredInterceptor();

	/**
	 * 是否拦截当前方法 如果返回true可以再Config中添加方法参数
	 * 
	 * @param config
	 */
	public boolean isMethodInterceptor(Config config) {
		Map<String,Annotation> annotations = new HashMap<String,Annotation>();
		if(targetAnnotations == null || targetAnnotations.length == 0){
			return isMethodInterceptor(config, annotations);
		}
		for(Class<Annotation> ann : targetAnnotations){
			Annotation annObject = null;
			try {
				annObject = ReflectUtil.getMethodInterfacesAnnotation(config.getBeanClass(), config.getMethod(), ann);
			} catch (NoSuchMethodException e) {
			}
			if(annObject != null){
				annotations.put(annObject.annotationType().getName(), annObject);
			}
		}
		if(!annotations.isEmpty()){
			return isMethodInterceptor(config, annotations);
		}
		return false;
	}

	/**
	 * 是否拦截当前方法 如果返回true可以再Config中添加方法参数
	 * @param config
	 * @param annotations key=注解类全名,value=注解对象(只有调用了setTargeAnnotations()方法并且传入了注解class才会传入该参数)
	 * @return
	 */
	public abstract boolean isMethodInterceptor(Config config,Map<String,Annotation> annotations);

	/**
	 * 设置注解,设置后只有当此class上或此Method上有此注解时才会调用getBeanMethodInterceptorsKeys方法
	 * 
	 * @param methodAnnotations
	 */
	public abstract Class<Annotation>[] getTargetAnnotations();
}
